package com.kgc.service.impl;

import com.github.pagehelper.PageInfo;
import com.kgc.dao.CategoryEsDao;
import com.kgc.dao.CategoryMapper;
import com.kgc.entity.Category;
import com.kgc.entity.Product;
import com.kgc.service.CategoryService;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class CategoryServiceImpl implements CategoryService {

    private int pages;
    private boolean temp = true;//是否需要将数据库数据导入elasticsearch

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private CategoryEsDao categoryEsDao;

    @Autowired
    private ElasticsearchRestTemplate ert;


    @Override
    public PageInfo<Category> selectCategoryBage(Map<String, Object> params) {
        if (temp) {
            initData();
        }
        NativeSearchQueryBuilder nsqb = new NativeSearchQueryBuilder();
        if (params.containsKey("searchName")) {
            nsqb.withQuery(QueryBuilders.matchQuery("name", params.get("searchName")));
        } else if (params.containsKey("searchType") && ((int) params.get("searchType") > 0)) {
            System.out.println("searchType:" + params.get("searchType"));
            nsqb.withFilter(QueryBuilders.termQuery("type", (int) params.get("searchType"))); // 添加type字段的搜索条件
        } else {
            nsqb.withQuery(QueryBuilders.matchAllQuery());
            System.out.println("无条件搜索");
        }
        // 设置排序字段和顺序
        String sortField = "id"; // 假设创建时间字段名为 type
        SortOrder sortOrder = SortOrder.ASC; // 默认升序
        nsqb.withSort(SortBuilders.fieldSort(sortField).order(sortOrder))
                .withPageable(PageRequest.of((int) params.get("pageNum") - 1, (int) params.get("pageSize")));
        HighlightBuilder hb = new HighlightBuilder();
        hb.field("name"); // 修改为正确的字段名
        hb.preTags("<font style='color:red'>");
        hb.postTags("</font>");
        nsqb.withHighlightBuilder(hb);
        SearchHits<Category> searchHits = ert.search(nsqb.build(), Category.class);
        PageInfo<Category> pageInfo = new PageInfo<>();
        ArrayList<Category> list = new ArrayList<>();
        for (SearchHit<Category> searchHit : searchHits.getSearchHits()) {
            Category category = searchHit.getContent();
            if (params.containsKey("searchName")) {
                List<String> highlightFields = searchHit.getHighlightField("name");
                if (highlightFields != null && !highlightFields.isEmpty()) {
                    category.setName(highlightFields.get(0));
                }
            }
            list.add(category);
        }
        pageInfo.setList(list);
        pageInfo.setPageNum((int) params.get("pageNum"));
        pageInfo.setPageSize((int) params.get("pageSize"));
        pageInfo.setTotal(searchHits.getTotalHits());
        pages = (int) searchHits.getTotalHits() % pageInfo.getPageSize() > 0 ? (int) searchHits.getTotalHits() / pageInfo.getPageSize() + 1 : (int) searchHits.getTotalHits() / pageInfo.getPageSize();
        pageInfo.setPages(pages);
        System.out.println("搜索到的数据条数" + pageInfo.getTotal());
        System.out.println("搜索到的数据页数" + pageInfo.getPages());
        return pageInfo;
    }


    @Override
    public void allCategory() {
        categoryEsDao.saveAll(categoryMapper.getAllCategory());
    }

    public void initData() {
        categoryEsDao.deleteAll();
        allCategory();
        System.out.println("将数据库中全部数据导入elasticsearch");
        temp = !temp;
    }


    @Override
    public int addCategory(Category category) {
        temp = !temp;
        return categoryMapper.addCategory(category);
    }

    @Override
    public int updateCategory(Category category) {
        temp = !temp;
        return categoryMapper.updateCategory(category);
    }

    @Override
    public int deleteCategory(int id) {
        temp = !temp;
        return categoryMapper.deleteCategory(id);
    }

    @Override
    public int getProductByCategoryId(int id) {

        return categoryMapper.getProductByCategoryId(id);
    }

    @Override
    public int getSonCountByCategoryId(int id) {

        return categoryMapper.getSonCountByCategoryId(id);
    }

    @Override
    public List<Category> getType1Category() {
        return categoryMapper.getType1Category();
    }

    @Override
    public List<Category> getType2Category(int id) {
        return categoryMapper.getType2Category(id);
    }

    @Override
    public List<Category> getType3Category(int id) {
        return categoryMapper.getType3Category(id);
    }

    @Override
    public Category getCategoryById(int id) {
        return categoryMapper.getCategoryById(id);
    }


    @Override
    public Category getCategoryByName(String name, int type) {
        return categoryMapper.getCategoryByName(name, type);
    }


    @Override
    public List<Category> getAllCategoryAndChild() {
        List<Category> flatCategories = categoryMapper.getAllCategory(); // 从数据库获取所有分类
        return buildCategoryTree(flatCategories);

    }

    @Override
    public List<Product> getProductsByCategoryId(int id) {
        return categoryMapper.getProductsByCategoryId(id);
    }


    public List<Category> buildCategoryTree(List<Category> categories) {
        // 按 parentId 分组存储子分类
        Map<Integer, List<Category>> parentIdToChildren = new HashMap<>();
        for (Category category : categories) {
            category.setProducts(categoryMapper.getProductsByCategoryId(category.getId()));
            Integer parentId = category.getParentId();
            parentIdToChildren.computeIfAbsent(parentId, k -> new ArrayList<>()).add(category);
        }
        // 获取根分类（假设 parentId=0 或无 parentId 的为根）
        List<Category> rootCategories = parentIdToChildren.getOrDefault(0, new ArrayList<>());

        // 递归填充子分类
        for (Category root : rootCategories) {
            populateChildren(root, parentIdToChildren);
        }
        return rootCategories;
    }

    private static void populateChildren(Category parent, Map<Integer, List<Category>> parentIdToChildren) {
        List<Category> children = parentIdToChildren.get(parent.getId());
        if (children != null) {
            // 设置子分类
            parent.setChildren(children);
            // 递归处理子分类的子分类
            for (Category child : children) {
                populateChildren(child, parentIdToChildren);
                // 可选：设置 parentName
                child.setParentName(parent.getName());
            }
        }
    }


}
